﻿using System;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Urs.Admin.Models.Users;
using Urs.Core;
using Urs.Data.Domain.Users;
using Urs.Services.Users;
using Urs.Services.Localization;
using Urs.Services.Logging;
using Urs.Services.Security;
using Urs.Framework;
using Urs.Framework.Controllers;
using Urs.Framework.Extensions;
using Urs.Framework.Kendoui;

namespace Urs.Admin.Controllers
{
    [AdminAuthorize]
    public partial class UserRoleController : BaseAdminController
    {
        #region Fields

        private readonly IUserService _userService;
        private readonly ILocalizationService _localizationService;
        private readonly IActivityLogService _activityLogService;
        private readonly IPermissionService _permissionService;

        #endregion

        #region Constructors

        public UserRoleController(IUserService userService,
            ILocalizationService localizationService, IActivityLogService activityLogService,
            IPermissionService permissionService)
        {
            this._userService = userService;
            this._localizationService = localizationService;
            this._activityLogService = activityLogService;
            this._permissionService = permissionService;
        }

        #endregion

        public IActionResult Index()
        {
            return RedirectToAction("List");
        }

        public IActionResult List()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            return View();
        }

        [HttpPost]
        public IActionResult ListJson(PageRequest command)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            var userRoles = _userService.GetAllUserRoles(true);
            var result = new ResponseResult
            {
                data = userRoles.Select(x => x.ToModel<UserRoleModel>()),
                count = userRoles.Count()
            };
            return Json(result);
        }

        public IActionResult Create()
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            var model = new UserRoleModel();
            //default values
            model.Active = true;
            return View(model);
        }

        [HttpPost]
        public IActionResult Create(UserRoleModel model, bool continueEditing)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            if (ModelState.IsValid)
            {
                var userRole = model.ToEntity<UserRole>();
                _userService.InsertUserRole(userRole);

                //activity log
                _activityLogService.InsertActivity("AddNewUserRole", _localizationService.GetResource("ActivityLog.AddNewUserRole"), userRole.Name);

                return continueEditing ? RedirectToAction("Edit", new { id = userRole.Id }) : RedirectToAction("List");
            }

            //If we got this far, something failed, redisplay form
            return View(model);
        }

        public IActionResult Edit(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            var model = new UserRoleModel();
            var userRole = _userService.GetUserRoleById(id);
            if (userRole != null)
                model = userRole.ToModel<UserRoleModel>();

            var permissions = _permissionService.GetAllPermissionRecords();
            var mappings = _permissionService.GetPermissionRecordUserMappings(userRole.Id);
            foreach (var item in permissions)
            {
                var pr = mappings.FirstOrDefault(q => q.PermissionRecordId == item.Id);
                var permission = new UserRoleModel.PermissionModel()
                {
                    Name = item.Name,
                    SystemName = item.SystemName,
                    Checked = pr != null
                };
                model.Permissions.Add(permission);
            }
            return View(model);
        }

        [HttpPost]
        public IActionResult Edit(UserRoleModel model)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            var userRole = _userService.GetUserRoleById(model.Id);
            if (userRole == null)
            {
                var userRoles = model.ToEntity<UserRole>();
                _userService.InsertUserRole(userRoles);

                //activity log
                _activityLogService.InsertActivity("AddNewUserRole", _localizationService.GetResource("ActivityLog.AddNewUserRole"), userRoles.Name);

                return Json(new { success = 1 });
            }
            else
            {
                if (ModelState.IsValid)
                {
                    if (userRole.IsSystemRole && !model.Active)
                        throw new UrsException(_localizationService.GetResource("Admin.Users.UserRoles.Fields.Active.CantEditSystem"));

                    if (userRole.IsSystemRole && !userRole.SystemName.Equals(model.SystemName, StringComparison.InvariantCultureIgnoreCase))
                        throw new UrsException(_localizationService.GetResource("Admin.Users.UserRoles.Fields.SystemName.CantEditSystem"));

                    userRole = model.ToEntity(userRole);

                    _userService.UpdateUserRole(userRole);

                    return Json(new { success = 1 });
                }

                return Json(new { success = 1 });

            }
        }

        [HttpPost]
        public IActionResult Delete(int id)
        {
            if (!_permissionService.Authorize(StandardPermissionProvider.ManageUserRoles))
                return HttpUnauthorized();

            var userRole = _userService.GetUserRoleById(id);
            if (userRole == null)
                return Json(new { error = 1 });

            try
            {
                _userService.DeleteUserRole(userRole);

                //activity log
                _activityLogService.InsertActivity("DeleteUserRole", _localizationService.GetResource("ActivityLog.DeleteUserRole"), userRole.Name);

                return Json(new { success = 1 });
            }
            catch (Exception exc)
            {
                return Json(new { error = 1 });
            }

        }

    }
}
